using Autofac;
using CommonHelper;
using CommonHelper.AutofacCommon;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
using NLogInfo;
using Order.MicroService.Api.Filters;
using Order.MicroService.Api.Middleware;
using Order.MicroService.Domain;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json.Linq;
using System.IO;
using Order.MicroService.Models;
using Order.MicroService.Api.Config;
using System;
using System.Reflection;

namespace Order.MicroService.Api
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            #region 配置AutoMapper           
            //手动加载Model.dll 程序集
            var assembly = AssemblyName.GetAssemblyName(Directory.GetFiles(AppContext.BaseDirectory, "CommonHelper.dll")[0]);
            AppDomain.CurrentDomain.Load(assembly);
            //配置AutoMapper
            services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
            #endregion

            #region 配置IdentityServer4
            AuthorizeConfig.RegisterAuthorizationServer(services);
            #endregion

            #region 添加异常处理过滤器
            services.AddControllers(options => options.Filters.Add(typeof(GlobalExceptionFilterAsync)))
                .AddJsonOptions(options =>
                {
                    //解决返回实体类和结果首字母小写(驼峰样式)的问题
                    options.JsonSerializerOptions.PropertyNamingPolicy = null;
                    options.JsonSerializerOptions.DictionaryKeyPolicy = null;
                });
            #endregion

            #region 配置Swagger
            SwaggerConfig.Register(services);
            #endregion

            #region 配置跨域
            CorsConfig.RegisterCors(services);
            #endregion

            #region 配置中心AgileConfig
            services.AddAgileConfig();
            #endregion

            #region 数据库配置
            services.AddDbContext<MyDbContext>(options => options.UseSqlServer(
                //dev
                //JObject.Parse(Configuration["OrderServiceDev:OrderServiceAppsettings.json"])["ConnectionStrings"]["dbConnections"].ToString()));
                //Prod
                JObject.Parse(Configuration["OrderServicePro:OrderServiceProAppsettings"])["ConnectionStrings"]["dbConnections"].ToString()));
            #endregion

            #region 配置HttpClient
            //命名模式注册HttpClient
            HttpClientConfig.Register(services);

            //类型模式注册HttpClient
            HttpClientConfig.RegisterTypeClients(services);
            #endregion
        }

        public void ConfigureContainer(ContainerBuilder builder)
        {
            // 直接用Autofac注册我们自定义的 IOC 容器
            builder.RegisterModule(new AutofacModuleRegister());
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseMiddleware<ExceptionHandlingMiddleware>();
            }
            app.UseSwagger();
            app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Order.MicroService.Api v1"));

            app.UseRouting();

            // 各个微服务之间接入Ocelot+IdentityServer4 之后，要进行认证
            //app.UseAuthentication();            

            app.UseAuthorization();

            app.UseCors("CorsPolicy");

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });

            // Consul注册  之所以不成功是AgileConfig中url前面有空格的问题，大坑！
            this.Configuration.ConsulRegistry(app);
        }
    }
}
